﻿using HelperFromTheSkeleton.ExtendMethod;
using HelperFromTheSkeleton.Model.DomainModels;
using HelperFromTheSkeleton.Model.TreeModels;

namespace HelperFromTheSkeleton.Convert
{
    /// <summary>
    /// 树的转换
    /// </summary>
    public static class TreeConvert
    {
        /// <summary>
        /// Domain实体转树结构
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="domain"></param>
        /// <returns></returns>
        public static List<ResultT> EntityToTreeList<ResultT, EntityT>(ICollection<EntityT> domain) where ResultT : BaseTree<ResultT>, new() where EntityT : TreeBaseDomain
        {
            var domainList = domain.ToList();
            List<ResultT> roots = domain.Where(m => m.ParentID == null).Select(m =>
            {
                var result = new ResultT();
                m.CopyProperty(result);
                return result;
            }).ToList();
            if (roots.Count > 0)
            {
                for (int i = 0; i < roots.Count; i++)
                {
                    roots[i] = GetTreeByRecursion(roots[i], domain);
                }
            }
            return roots;
        }

        /// <summary>
        /// 通过递归获取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        private static ResultT GetTreeByRecursion<ResultT, EntityT>(ResultT root, ICollection<EntityT> domain) where ResultT : BaseTree<ResultT>, new() where EntityT : TreeBaseDomain
        {
            var parentID = root.ID;
            root.Children = domain.Where(m => m.ParentID == parentID).Select(m =>
            {
                var result = new ResultT {  };
                m.CopyProperty(result);
                return result;
            }).ToList();
            if (root.Children?.Count > 0)
            {
                for (int i = 0; i < root.Children.Count; i++)
                {
                    root.Children[i] = GetTreeByRecursion(root.Children[i], domain);
                }
            }
            return root;
        }
    }
}
